<?php
namespace DataCube\DataCubeAggregation\Functions;

class Formatter
{
    public $cellFormat = [
        'decimal',
        'fixed_decimal',
        'whole',
        'integers',
        'percentage',
        'DateTime',
        'Date',
        'Time',
        'DateTimeTimeZone',
        'duration',
        'text',
        'boolean',
        'binary',
        'Scientific',
        'Currency',
        'custom'
    ];

    public function format($value, $method = 'Text', $options = [])
    {
        switch (strtolower($method)) {
            case 'text':
                return sprintf('%s', $value);
            case 'money':
                setlocale(LC_MONETARY,"en_US");
                return number_format("The price is %i", 2, '.');
            default:
                return $value;
        }
    }

    public $numeric_units_suffix = [
        0 => '',
        1 => '千',
        2 => '万',
        3 => '百万',
        4 => '千万',
        5 => '亿',
        6 => '十亿',
    ];

    public $numeric_units_transfer = [
        'nan' => 0,
        'thousand' => 1,
        'ten_thousand' => 2,
        'million' => 3,
        'ten_million' => 4,
        'hundred_million' => 5,
        'billion' => 6,
    ];

    /**
     * available_decimal 有效小数点
     */
    public function numbers($number, $unit = 0, ?string $prefix = null, ?string $suffix = null, $available_decimal = false, int $decimals = 0, ?string $decimal_separator = ".", ?string $thousands_separator = "")
    {
        $prefixStr = $prefix ?? '';
        $suffixStr = $suffix ?? '';
        // count available decimal digits
        if ($available_decimal) {
            $decimals = $this->countAvailableDecimals($number, $decimals, $decimal_separator);
        }

        switch ($unit) {
            case 0:
                $tempNum = floatval($number);
                break;
            case 1:
                $tempNum = floatval($number / 1000);
                break;
            case 2:
                $tempNum = floatval($number / 10000);
                break;
            case 3:
                $tempNum = floatval($number / 1000000);
                break;
            case 4:
                $tempNum = floatval($number / 10000000);
                break;
            case 5:
                $tempNum = floatval($number / 100000000);
                break;
            default:
                $tempNum = $number;
                break;
        }

        $numberStr = sprintf("%." . $decimals . "f", substr(sprintf("%." . ($decimals + 1) . "f", $tempNum), 0, -1));

        // thousands_separator
        if (isset($thousands_separator) && $thousands_separator != "") {
            $numberStr = $this->getNumberWithThousandsSeparator($numberStr);
        }
        return $prefixStr . $numberStr . $this->numeric_units_suffix[$unit] . $suffixStr;
    }

    
    private function countAvailableDecimals($number, int $decimals, $decimal_separator = '.')
    {
        $available_decimal_point = strrpos(sprintf("%f", floatval($number)), $decimal_separator);
        if ($available_decimal_point) {
            $str = substr(sprintf("%f", floatval($number)), $available_decimal_point + 1);
            $str_arr = str_split($str);
            foreach ($str_arr as $key => $value) {
                if (intval($value) == 0) {
                    ++$decimals;
                } else {
                    break;
                }
            }
        }

        return $decimals;
    }

    private function getNumberWithThousandsSeparator(string $numberStr)
    {
        $strArr = explode('.', $numberStr);

        $leftStr = $strArr[0];

        if (isset($strArr[1])) {
            $rightStr = $strArr[1];
        } else {
            $rightStr = null;
        }
        $len = strlen($leftStr);
        if ($len % 3 == 0) {
            $temp = str_split($leftStr, 3);
        } else {
            $left = substr($leftStr, 0, $len % 3);
            $temp = str_split(substr($leftStr, strlen($left)), 3);

            //然后把left部分放压入数组最前面
            array_unshift($temp, $left);
        }
        // 小数点拼接
        if (is_null($rightStr)) {
            $numberStr = implode(",", $temp);
        } else {
            $numberStr = implode(",", $temp) . '.' . $rightStr;
        }
        return $numberStr;
    }

    function getFloatLength($num){

        $count = 0;

        $temp = explode('.', $num);

        if (sizeof($temp) > 1) {

            $decimal = end($temp);

            $count = strlen($decimal);

        }

        return $count;
    }
}